package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("/dish")
@Api(tags = "菜品相关接口")
public class DishController {
    @Autowired
    private DishService dishService;
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 分页查询
     *
     * @param page
     * @param pageSize
     * @return
     */

    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name) {
        //分页查询
        Page<Dish> dishPage = new Page<>(page, pageSize);
        Page<DishDto> dishDtoPage = new Page<>();

        QueryWrapper<Dish> dishQueryWrapper = new QueryWrapper<>();
        dishQueryWrapper.lambda().like(null != name, Dish::getName, name);
        dishQueryWrapper.lambda().orderByDesc(Dish::getUpdateTime);
        dishService.page(dishPage, dishQueryWrapper);

        //对象拷贝
        BeanUtils.copyProperties(dishPage, dishDtoPage, "records");

        List<Dish> records = dishPage.getRecords();//dishs(不包含菜品分类名称的)
        List<DishDto> list = records.stream().map((item) -> {//item = dishs中的某个dish
            //造个空的菜品传递对象来接数据
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Long categoryId = item.getCategoryId();//分类id(dish中有个属性是categoryId)
            //根据id查询分类对象
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return dishDto;
        }).collect(Collectors.toList());
        dishDtoPage.setRecords(list);
        return R.success(dishDtoPage);
    }

    /**
     * 添加菜品
     *
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> add(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());
        dishService.saveWithFlavor(dishDto);

        //清理某个分类下面的菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);

        return R.success("添加成功了鉄子");
    }

    /**
     * 根据id查找菜品和他的口味
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
//直接保存不能保存菜品口味
//    public R<Dish> getByID(@PathVariable Long id) {
//        log.info("菜品的id:" + id);
//        Dish dish = dishService.getById(id);
//        return R.success(dish);
//    }

    public R<DishDto> get(@PathVariable Long id) {
        log.info("获取菜品的id:" + id);
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改菜品及其口味
     *
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> updateWithFlavor(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());
        dishService.updateWithFlavor(dishDto);

        //清理某个分类下面的菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);

        return R.success("修改成功了鉄子");
    }

    /**
     * 逻辑删除菜品
     *
     * @param ids
     * @return
     */
    @DeleteMapping()
    public R<String> deleteWithFlavor(@RequestParam List<Long> ids) {
        log.info("要删除的菜品id为:" + ids);

        for (Long id : ids) {
            log.info("状态码为:" + dishService.getById(id).getStatus());

            if (0 != dishService.getById(id).getStatus()) {
                return R.error("大锅,删除之前是不是没有设置停售啊?");
            }
        }

        dishService.removeWithFlavor(ids);
        return R.success("修改成功了鉄子");
    }

    /**
     * 修改菜品状态
     *
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    public R<String> updateStatus(@PathVariable Integer status, @RequestParam List<Long> ids) {
        log.info("status:{},ids:{}", status, ids);
        for (Long id : ids) {
            Dish dish = dishService.getById(id);
            dish.setStatus(status);
            dishService.updateById(dish);
        }
        return R.success("菜品状态修改成功了鉄子!");
    }

    /**
     * 根据前端穿过来的菜品分类的id查询其包含的所有菜品
     *
     * @param dish
     * @return
     */
    /*
     * 根据CategoryId获取对应的dishs
     * 1.新建一个dish的过滤器
     * 2.过滤条件是dish的categoryid和从前端的到一直并且不为空
     * 3.过滤后的dish返回到前端
     * */

    /*
     * 开发前台的时候发现仅仅返回dish是不够的
     * 要把口味也加到菜品里面返回
     * 那就要返回dishdto*/

    //改造:先查询redis缓存,没有再查数据库并保存到缓存中
    @GetMapping("/list")
    public R<List<DishDto>> getDishByCategoryId(Dish dish) {
        List<DishDto> dishDtoList = null;
//动态构造key
        String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();
        //dish_1397844391040167938_1
//先从redis中获取缓存数据
        dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);
        if(dishDtoList != null){
            //如果存在，直接返回，无需查询数据库
            return R.success(dishDtoList);
        }

        Long categoryId = dish.getCategoryId();
        QueryWrapper<Dish> dishQueryWrapper = new QueryWrapper<>();
        dishQueryWrapper.lambda().eq(null != categoryId, Dish::getCategoryId, categoryId);
        dishQueryWrapper.lambda().eq(Dish::getStatus, 1);//起售的
        dishQueryWrapper.lambda().orderByDesc(Dish::getUpdateTime);
        List<Dish> dishes = dishService.list(dishQueryWrapper);//获取特定套餐id下的所有菜品

        if (dishes != null) {
            List<DishDto> dishDtos = dishes.stream().map(new Function<Dish, DishDto>() {
                @Override
                public DishDto apply(Dish item) {
                    //查询到每一个dish
                    Long id = item.getId();//获取每个dish的id
                    //查询口味表List<flavor>
                    QueryWrapper<DishFlavor> dishFlavorQueryWrapper = new QueryWrapper<>();
                    dishFlavorQueryWrapper.lambda().eq(null != id, DishFlavor::getDishId, id);
                    List<DishFlavor> dishFlavors = dishFlavorService.list(dishFlavorQueryWrapper);
                    //构件dishdto并把dish里的属性拷贝进去
                    DishDto dishDto = new DishDto();
                    BeanUtils.copyProperties(item, dishDto);
                    //设置dishdto的口味
                    dishDto.setFlavors(dishFlavors);
                    return dishDto;
                }
            }).collect(Collectors.toList());
//如果不存在，需要查询数据库，将查询到的菜品数据缓存到Redis
            redisTemplate.opsForValue().set(key,dishDtos,60, TimeUnit.MINUTES);
            return R.success(dishDtos);
        }
        return R.error("此分类下无菜品");
    }


}
